#!/bin/bash

###
# The version
#
VERSION=0.0.1

###
# Functions here...
# 

_die_clean(){
    rm -f config.mak
    rm -f config.h
    rm -f tmp.c
    exit $1
}

bits64(){
    case $1 in
        x86_64|ia64) return 0 ;;
        *) return 1 ;;
    esac
}

bits32(){
    case $1 in
        i386) return 0 ;;
        *) return 1 ;;
    esac
}

###
# First make the config.mak file.
#

if [ -e config.mak ]; then
    rm config.mak
fi

###
# Set the version string here
#
echo "VERSION=$VERSION" >> config.mak

###
# Parse user supplied arguments.
#

###
# Start the config'ing
#

# check for linux, right now its not garanteed to run on anything else.
echo -n "Checking build environment: "
system=`uname -s 2>&1`

if [ "$system" = "Linux" ]; then
    echo "sane."
else
    echo "FAILED"
    echo "You do not appear to have linux. You need linux for the moment."
    _die_clean 1
fi


_proc_name=unknown
PERL=`which perl 2>&1`
if [ -x $PERL ]; then # Use perl to parse the /proc/cpuinfo file for proc info
    _proc_name=`perl -e '
    open(CPU, "/proc/cpuinfo");
    while (<CPU>){
	if (/model\ name/){
	    ($blah, $proc_name) = split(/: /, $_);
	    print $proc_name;
	    exit;
	}
    }' 2>&1`

fi

echo "Processor: $_proc_name"

procs=unknown

if [ -x $PERL ]; then
    procs=`perl -e '
    $count = 0;
    open(CPU, "/proc/cpuinfo");
    while (<CPU>){
	if (/^processor/){
	    $count++;
	}
    }
    print "$count";' 2>&1`
fi

echo "Processors: $procs"

# Set the architecture
_arch=`uname -m 2>&1`
case $_arch in 
    x86_64)
	arch=-march=k8
	proc=x86_64
	;;
    i[3-9]86)
	arch=-march=i386
	proc=i386
	;;
    *)
	arch=-march=generic
	proc=generic
	;;
esac

echo "Compiling for architecture: $proc"

# Find out some info about our processor

_proc_use_mmx="#  undef _SWRAM_HAVE_MMX"
_proc_use_sse="#  undef _SWARM_HAVE_SSE"
_proc_use_sse2="#  undef _SWARM_HAVE_SSE2"
_proc_use_sse3="#  undef _SWARM_HAVE_SSE3"
_proc_use_3dnow="#  undef _SWARM_HAVE_3DNow"

echo -n "Checking for MMX: "
_have_mmx=`grep mmx /proc/cpuinfo`
if [ "$_have_mmx" != "" ]; then
    _proc_use_mmx="#  define _SWARM_HAVE_MMX"
    echo "yes."
else
    echo "no."
fi

echo -n "Checking for SSE: "
_have_sse=`grep sse /proc/cpuinfo`
if [ "$_have_sse" != "" ]; then
    _proc_use_sse="#  define _SWARM_HAVE_SSE"
    echo "yes."
else
    echo "no."
fi

echo -n "Checking for SSE2: "
_have_sse2=`grep sse2 /proc/cpuinfo`
if [ "$_have_sse2" != "" ]; then
    _proc_use_sse2="#  define _SWARM_HAVE_SSE2"
    echo "yes."
else
    echo "no."
fi

echo -n "Checking for SSE3: "
_have_sse3=`grep sse3 /proc/cpuinfo`
if [ "$_have_sse3" != "" ]; then
    _proc_use_sse3="#  define _SWARM_HAVE_SSE3"
    echo "yes."
else
    echo "no."
fi

echo -n "Checking for 3dnow: "
_have_3dnow=`grep 3dnow /proc/cpuinfo`
if [ "$_have_3dnow" != "" ]; then
    _proc_use_3dnow="#  define _SWARM_HAVE_3DNow"
    echo "yes."
else
    echo "no."
fi

C_FLAGS=
C_TEST_FLAGS=
if [ "$_have_mmx" != "" ]; then
    C_FLAGS=$C_FLAGS" -mmmx"
    C_TEST_FLAGS=$C_TEST_FLAGS" -mmmx"
fi
if [ "$_have_sse" != "" ]; then
    C_FLAGS=$C_FLAGS" -msse"
    C_TEST_FLAGS=$C_TEST_FLAGS" -msse"
fi
if [ "$_have_sse2" != "" ]; then
    C_FLAGS=$C_FLAGS" -msse2"
    C_TEST_FLAGS=$C_TEST_FLAGS" -msse2"
fi
if [ "$_have_sse3" != "" ]; then
    C_FLAGS=$C_FLAGS" -msse3"
    C_TEST_FLAGS=$C_TEST_FLAGS" -msse3"
fi
if [ "$_have_3dnow" != "" ]; then
    C_FLAGS=$C_FLAGS" -m3dnow"
    C_TEST_FLAGS=$C_TEST_FLAGS" -m3dnow"
fi

# check for gcc.
echo -n "Checking for gcc: "
GCC=`which gcc 2>&1`

if [ -x $GCC ]; then
    echo "CC=gcc" >> config.mak
    echo "yes.";
else
    echo "FAILED"
    echo "gcc does not appear to be on your system. You need to have gcc."
    echo "Get gcc, then try again."
    _die_clean 1
fi

# Check for gdb
echo -n "Checking for gdb: "

_gdb=`which gdb 2>&1`
if [ -x $_gdb ]; then
    have_gdb=true
    C_FLAGS=$C_FLAGS" -gstabs"
    C_TEST_FLAGS=$C_TEST_FLAGS" -gstabs"
fi

if [ "$have_gdb" = "true" ]; then
    echo "yes."
else
    echo "no."
fi

# check our gcc opts
echo -n "Checking if gcc works: "
C_FLAGS=$C_FLAGS" -fPIC -Wall -c -O2 $arch"
C_TEST_FLAGS=$C_TEST_FLAGS" -Wall"

# make a temp c file to do the tests on
cat >tmp.c <<EOF
int main(int argc, char **argv){
  return 0;
}
EOF

$GCC tmp.c -o tmp 2>&1 >/dev/null
gcc_res=$?
./tmp
tmp_res=$?

if [ "$gcc_res" != "0" ]; then
    echo "PANIC: gcc does not appear to work."
    _die_clean 1
elif [ "$tmp_res" != "0" ]; then
    echo "PANIC: gcc does not appear to work."
    _die_clean 1
else
    rm tmp
fi

$GCC $C_FLAGS -o tmp tmp.c 2>&1 >/dev/null

if [ "$?" != "0" ]; then
    echo "PANIC: gcc does not appear to work."
    _die_clean 1
else
    rm tmp
fi

rm -f tmp.c

echo "yes."

# Check for pthread

echo -n "Checking for pthreads: "

# make a temp c file to do the tests on
cat >tmp.c <<EOF
#include <pthread.h>
int main(int argc, char **argv){
  return 0;
}
EOF

$GCC tmp.c -o tmp -lpthread
if [ "$?" != "0" ]; then
    echo "You do not have pthreads installed properly."
    _die_clean 1
else 
    echo "yes."
    rm -f tmp.c tmp
fi

# Check for gtk+-2.0

echo -n "Checking for gtk+-2.0: "

pkg-config gtk+-2.0
if [ "$?" == "0" ]; then
    echo "Yes."
else 
    echo "No."
    echo "You must have gtk+-2.0 installed."
    _die_clean 1
fi

GTK_LIBS=`pkg-config --libs gtk+-2.0`
GTK_CFLAGS=`pkg-config --cflags gtk+-2.0`

echo "C_FLAGS=$GTK_CFLAGS $C_FLAGS" >> config.mak
echo "C_TEST_FLAGS=$GTK_CFLAGS $C_TEST_FLAGS -O2 $arch" >> config.mak

echo "GTK_LIBS=$GTK_LIBS" >> config.mak

### Here we determine whether to use yasm or nasm.

_asm=

# Check for yasm and nasm
echo -n "Checking for yasm: "
YASM=`which yasm 2>/dev/null`
if [ "$YASM" != "" ]; then
    if [ -x $YASM ]; then
	echo "Yes."
    else
	echo "No."
    fi
else
    echo "No."
fi

echo -n "Checking for nasm: "
NASM=`which nasm 2>/dev/null`
if [ "$NASM" != "" ]; then
    if [ -x $NASM ]; then
	echo "Yes."
    else
	echo "No."
    fi
else
    echo "No."
fi
if bits32 $proc ; then
    if [ "$YASM" == "" ] && [ "$NASM" == "" ]; then
	echo "You must have yasm or nasm."
	echo "Error."
	_die_clean 1
    fi
elif bits64 $proc ; then
    if [ "$YASM" == "" ]; then
	echo "You must have yasm for x86_64."
	echo "Error."
	_die_clean 1
    fi
fi

# Determine which assmebler to use.
echo -n "Using nasm or yasm: "

if bits32 $proc ; then
    if [ -x $NASM ]; then
        _asm=nasm
    elif [ -x $YASM ]; then
        # Fall back on to yasm
        _asm=yasm
    else
        echo "Error: You need either yasm or nasm to compile this"
        _die_clean 1
    fi
fi

if bits64 $proc ; then
    if [ -x $YASM ]; then
        _asm=yasm
    else
        echo "Error: You need yasm to compile this for x86_64"
        _die_clean 1
    fi
fi

if bits64 $proc ; then
    ASM_FLAGS="-f elf64"
else
    ASM_FLAGS="-f elf"
fi

echo "$_asm."
echo "ASM=$_asm" >> config.mak
echo "ASM_FLAGS=$ASM_FLAGS" >> config.mak

### This is specific to this program.
if bits64 $proc ; then
    echo "NATIVE=native64.o" >> config.mak
else
    echo "NATIVE=native32.o" >> config.mak
fi

# Generate files now

echo "Generating config.mak: OK"
echo -n "Generating config.h: "

if [ -e config.h ]; then
    rm -f config.h
fi

# Set all of the defines here

if [ "$proc" = "x86_64" ]; then
    x86_64="#  define _SWARM_PROC_x86_64"
else
    x86_64="#  undef _SWARM_PROC_x86_64"
fi

cat >config.h <<EOF
#ifndef _CONFIG_H
#  define _CONFIG_H
#  define _SWARM_VERSION       "$VERSION"
#  define _SWARM_ARCH          "$proc"
#  define _SWARM_PROC          "$_proc_name"
#  define _SWARM_PROCS         $procs
$x86_64
$_proc_use_mmx
$_proc_use_sse
$_proc_use_sse2
$_proc_use_sse3
$_proc_use_3dnow
#endif
EOF

echo "OK"
